package cn.lili.modules.distribution.serviceimpl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.AuthUser;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.security.enums.SceneEnums;
import cn.lili.modules.distribution.entity.dos.Distribution;
import cn.lili.modules.distribution.entity.dos.DistributionGoods;
import cn.lili.modules.distribution.entity.dos.DistributionSelectedGoods;
import cn.lili.modules.distribution.entity.dto.DistributionGoodsSearchParams;
import cn.lili.modules.distribution.entity.vos.DistributionGoodsVO;
import cn.lili.modules.distribution.entity.vos.DistributionInfoVO;
import cn.lili.modules.distribution.mapper.DistributionGoodsMapper;
import cn.lili.modules.distribution.service.DistributionGoodsService;
import cn.lili.modules.distribution.service.DistributionSelectedGoodsService;
import cn.lili.modules.distribution.service.DistributionService;
import cn.lili.modules.goods.client.CategoryClient;
import cn.lili.modules.goods.client.GoodsClient;
import cn.lili.modules.goods.entity.dos.Category;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.member.client.UserClient;
import cn.lili.modules.member.entity.dos.User;
import cn.lili.modules.search.entity.dos.EsGoodsIndex;
import cn.lili.modules.system.client.SettingClient;
import cn.lili.modules.system.entity.dos.Setting;
import cn.lili.modules.system.entity.dto.WindowSetting;
import cn.lili.modules.system.entity.enums.SettingEnum;
import cn.lili.mybatis.util.PageUtil;
import cn.lili.mybatis.util.SceneHelp;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;


/**
 * 分销商品接口实现
 *
 * @author pikachu
 * @since 2020-03-24 23:04:56
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class DistributionGoodsServiceImpl extends ServiceImpl<DistributionGoodsMapper, DistributionGoods> implements DistributionGoodsService {

    /**
     * 分销员
     */
    private final DistributionService distributionService;

    /**
     * 分销商品业务
     */
    private final DistributionSelectedGoodsService distributionSelectedGoodsService;

    /**
     * 规格商品
     */
    private final GoodsClient goodsClient;

    private final SettingClient settingClient;

    private final UserClient userClient;
    /**
     * 分类client
     */
    private final CategoryClient categoryClient;

    private final ElasticsearchOperations restTemplate;

    @Override
    public Page<DistributionGoodsVO> goodsPage(DistributionGoodsSearchParams searchParams) {
        //获取商家的分销商品列表
        if (Objects.requireNonNull(UserContext.getCurrentUser()).getScene().equals(SceneEnums.STORE)) {
            return initDistributionGoodsVO(this.baseMapper.getDistributionGoodsVO(PageUtil.initPage(searchParams), searchParams.storeQueryWrapper()),null);
        } else if (UserContext.getCurrentUser().getScene().equals(SceneEnums.MEMBER)) {
            //判断当前登录用户是否为分销员
            Distribution distribution = distributionService.getDistribution();
            if (distribution != null) {
                //判断查看已选择的分销商品列表
                if (searchParams.isChecked()) {
                    return initDistributionGoodsVO(this.baseMapper.selectGoods(PageUtil.initPage(searchParams), searchParams.distributionQueryWrapper(),
                            distribution.getId()),distribution.getId());
                } else {
                    return initDistributionGoodsVO(this.baseMapper.notSelectGoods(PageUtil.initPage(searchParams), searchParams.distributionQueryWrapper(),
                            distribution.getId()),distribution.getId());
                }
            }
            throw new ServiceException(ResultCode.DISTRIBUTION_NOT_EXIST);
        }
        //如果是平台则直接进行查询
        Page<DistributionGoodsVO> distributionGoodsVO = this.baseMapper.getDistributionGoodsVO(PageUtil.initPage(searchParams), searchParams.distributionQueryWrapper());
        return initDistributionGoodsVO(distributionGoodsVO,null);
    }

    /**
     * 重新设置返回值
     * */
    public Page<DistributionGoodsVO> initDistributionGoodsVO(Page<DistributionGoodsVO> page,String distributionId){
        List<DistributionGoodsVO> resultList = page.getRecords().stream().peek(distributionGoods -> {
            GoodsSku goodsSkuById = goodsClient.getGoodsSkuById(distributionGoods.getSkuId());
            if (goodsSkuById != null) {
                distributionGoods.setPrice(goodsSkuById.getPrice() + goodsSkuById.getGreenScore());
            }
            distributionGoods.setDistributionId(distributionId);
        }).toList();
        page.setRecords(resultList);
        return page;
    }

    /**
     * 根据条件查询分销商品信息
     *
     * @param distributionGoodsSearchParams 条件
     * @return 分销商品信息
     */
    @Override
    public DistributionGoods getDistributionGoods(DistributionGoodsSearchParams distributionGoodsSearchParams) {
        return this.getOne(distributionGoodsSearchParams.queryWrapper(), false);
    }

    @Override
    public List<DistributionGoods> distributionGoods(List<String> skuIds) {
        return this.list(new LambdaUpdateWrapper<DistributionGoods>().in(DistributionGoods::getSkuId, skuIds));
    }

    /**
     * 注意,此处skuIds为原逻辑,现逻辑的skuIds = goodIds
     * @param skuIds   goodIds
     */
    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public void checked(String skuIds, String storeId) {
        log.info("同步分销商品,进入checked方法,skuIds:{}", skuIds);
        AuthUser authUser = UserContext.getCurrentUser();
        if (authUser != null && StrUtil.isEmpty(storeId)) {
            storeId = Objects.requireNonNull(authUser).getExtendId();
        }
        log.info("同步分销商品, storeId:{},进入检查分销开关的方法", storeId);
        //检查分销功能开关
        distributionService.checkDistributionSetting();
        log.info("同步分销商品,检查分销功能开关结束");
        String[] skus = skuIds.split(",");
        log.info("同步分销商品,skuIds.split():{}", JSONObject.toJSONString(skus));
        for (String skuId : skus) {
            //判断是否存在分销商品，如果存在不能添加
            QueryWrapper queryWrapper = Wrappers.query().eq("sku_id", skuId);
            log.info("同步分销商品,判断是否存在分销商品，如果存在不能添加");
            if (this.getOne(queryWrapper) != null) {
                //throw new ServiceException(ResultCode.DISTRIBUTION_GOODS_DOUBLE);
                log.info("同步分销商品,商品存在,执行continue");
                continue;
            }
            GoodsSku goodsSku = goodsClient.getGoodsSkuByIdFromCache(skuId);
            log.info("同步分销商品,根据skuId(实则goods.getId)查询GoodsSku,skuId:{}", skuId);
            if (!goodsSku.getStoreId().equals(storeId)) {
                throw new ServiceException(ResultCode.USER_AUTHORITY_ERROR);
            }
            DistributionGoods distributionGoods = new DistributionGoods(goodsSku);

//            Setting setting = null;
//            if (goodsSku.getIsGreenGoods()) {
//                setting = settingClient.get("GREEN_GOODS");
//            } else {
//                setting = settingClient.get("NOT_GREEN_GOODS");
//            }
            //当前商品的绿色积分 * setting配置的比例 /  100
            Setting setting = settingClient.get(SettingEnum.WINDOW_SHOW.name());
            WindowSetting windowSetting = JSONUtil.toBean(setting.getSettingValue(), WindowSetting.class);

//            JSONObject jsonObject = JSONObject.parseObject(setting.getSettingValue());
            BigDecimal distributionProportion = BigDecimal.valueOf(goodsSku.getGreenScore()).multiply(BigDecimal.valueOf(Double.parseDouble(windowSetting.getWindows()))).divide(BigDecimal.valueOf(100));
            distributionGoods.setCommission(distributionProportion.doubleValue());
            this.save(distributionGoods);
            log.info("同步分销商品,根据skuId查询GoodsSku,执行save操作完成,参数为:{}", JSONObject.toJSONString(distributionGoods));
        }
    }

    @Override
    public void cancel(String id) {

        DistributionGoods distributionGoods = this.getById(id);

        SceneHelp.objectAuthentication(distributionGoods);

        this.removeById(id);

        //清除分销商已选择分销商品
        distributionSelectedGoodsService.remove(new QueryWrapper<DistributionSelectedGoods>().eq("distribution_goods_id", id));

    }


    /**
     * 根据openId查询是否是分销以及其橱窗商品
     * @param searchParams
     * @return
     */
    @Override
    public DistributionInfoVO getDistributionGoodByOpenId(DistributionGoodsSearchParams searchParams) {
        if(StrUtil.isBlank(searchParams.getOpenId())){
            throw new ServiceException("openId不可为空");
        }
        DistributionInfoVO vo =  new DistributionInfoVO();
        Page<DistributionGoodsVO> page = new Page<>();
        //根据openid查询是否是分销员
        User user = userClient.getByOpenId(searchParams.getOpenId(), SceneEnums.MEMBER.name());
        log.info("#getDistributionGoodByOpenId# 根据openid查询user信息,openid:{},结果:{}", searchParams.getOpenId(), (null == user ? null : JSONObject.toJSONString(user)));
        if (null == user) {
            throw new ServiceException("未找到该用户");
        }
        Distribution dis = distributionService.selectDistributionByMemberId(user.getId());
        if (dis != null) {
            if (StrUtil.isBlank(searchParams.getCategoryId())) {
                page = initDistributionGoodsVO(this.baseMapper.selectGoods(PageUtil.initPage(searchParams), searchParams.distributionQueryWrapper(),
                        dis.getId()), dis.getId());
            } else {
                searchParams.setDistributionId(dis.getId());
                page = this.getDistributionGoodListByOpenIdAndCategoryInfo(searchParams);
            }
            //是分销员
            vo.setIsDistribution(1);
            vo.setGoodsPage(this.conversion(page));
            vo.setDistributionGoodsCount(Long.valueOf(page.getTotal()).intValue());
        }else{
            //不是分销员
            vo.setIsDistribution(0);
        }
        return vo;
    }

    /**
     * 获取是否会员，是否全返，是否绿色商品等信息
     * @param page 分销商品
     * @return 分销商品
     */
    private Page<DistributionGoodsVO> conversion(Page<DistributionGoodsVO> page) {
        if (CollectionUtil.isEmpty(page.getRecords())) {
            return page;
        }
        List<String> list = page.getRecords().stream().map(DistributionGoodsVO::getGoodsId).toList();
        for (String string : list) {
            log.info("11 == {} ", string);
            Page<EsGoodsIndex> esGoods = goodsClient.searchEsByGoodsId(string);
            log.info("222 == {}", JSONObject.toJSONString(esGoods));
            if (CollectionUtil.isNotEmpty(esGoods.getRecords())) {
                log.info("333 == {}", JSONObject.toJSONString(esGoods.getRecords()));
                for (EsGoodsIndex goodsIndex : esGoods.getRecords()) {
                    for (DistributionGoodsVO distributionGoodsVO : page.getRecords()) {
                        if (goodsIndex.getGoodsId().equals(distributionGoodsVO.getGoodsId())) {
                            log.info("444 == {},   {}", JSONObject.toJSONString(goodsIndex), JSONObject.toJSONString(distributionGoodsVO));
//                            BeanUtil.copyProperties(goodsIndex, distributionGoodsVO);
                            distributionGoodsVO.setCategoryPathSon(goodsIndex.getCategoryPathSon());
                            distributionGoodsVO.setVipPrice(goodsIndex.getVipPrice());
                            distributionGoodsVO.setRedPack(goodsIndex.getRedPack());
                            distributionGoodsVO.setIsGreenGoods(goodsIndex.getIsGreenGoods());
                            distributionGoodsVO.setMaxfNumber(goodsIndex.getMaxfNumber());
                            distributionGoodsVO.setIsCommonwealGoods(goodsIndex.getIsCommonwealGoods());
                            distributionGoodsVO.setIsVipGoods(goodsIndex.getIsVipGoods());
                            distributionGoodsVO.setIsResultGoods(goodsIndex.getIsResultGoods());
                            distributionGoodsVO.setIsGreenSecurities(goodsIndex.getIsGreenSecurities());
                            distributionGoodsVO.setGreenScore(goodsIndex.getGreenScore());
                            distributionGoodsVO.setIsMhGoods(goodsIndex.getIsMhGoods());
                            distributionGoodsVO.setIsTicket(goodsIndex.getIsTicket());
                            distributionGoodsVO.setIsMeal(goodsIndex.getIsMeal());
                            distributionGoodsVO.setVirtualBuyCount(goodsIndex.getVirtualBuyCount());
                            distributionGoodsVO.setIsDistributionGoods(goodsIndex.getIsDistributionGoods());
                            log.info("555 == {},   {}", JSONObject.toJSONString(goodsIndex), JSONObject.toJSONString(distributionGoodsVO));
                        }
                    }
                }
            }
        }
        return page;
    }


    /**
     * 根据openId查询是否是分销以及其橱窗商品数量
     * @param searchParams
     * @return
     */
    @Override
    public DistributionInfoVO getDistributionGoodCountByOpenId(DistributionGoodsSearchParams searchParams) {
        DistributionInfoVO vo = this.getDistributionGoodByOpenId(searchParams);
        vo.setGoodsPage(null);
        return vo;
    }

    /**
     * 根据openid查询分销商品分类
     * @param openId
     * @return
     */
    @Override
    public List<Category> getDistributionGoodCategroyListByOpenId(String openId) {
        if (StrUtil.isBlank(openId)) {
            throw new ServiceException("openId参数不可为空");
        }
        //分类返回的集合
        List<Category> categoryList = new ArrayList<>();
        //根据openid查询是否是分销员
        User user = userClient.getByOpenId(openId, SceneEnums.MEMBER.name());
        log.info("#getDistributionGoodByOpenId# 根据openid查询user信息,openid:{},结果:{}", openId, (null == user ? null : JSONObject.toJSONString(user)));
        if (null == user) {
            throw new ServiceException("未找到该用户");
        }
        Distribution dis = distributionService.selectDistributionByMemberId(user.getId());
        if (dis == null) {
            throw new ServiceException("该用户不是分销员");
        }
        //查询分销商品分类信息
        List<Goods> goodsList = baseMapper.selectDistributionGoodCategoryInfo(dis.getId());
        if (CollUtil.isNotEmpty(goodsList)) {
            //根据商品分类id查询分类信息
            List<String> categoryIdListParam = new ArrayList<String>();
            //获取分类首层
            for (Goods goods : goodsList) {
                if (StrUtil.isNotBlank(goods.getCategoryPath())) {
                    String[] categoryIdArray = goods.getCategoryPath().split(",");
                    if (categoryIdArray == null || categoryIdArray.length == 0) {
                        log.info("#getDistributionGoodCategroyListByOpenId# categoryIdListParam 分类字段为空,这里continue");
                        continue;
                    }
                    categoryIdListParam.add(categoryIdArray[0]);
                }
            }
            if (CollUtil.isEmpty(categoryIdListParam)) {
                log.info("#getDistributionGoodCategroyListByOpenId# categoryIdListParam 分类信息为空");
            }
            categoryList = categoryClient.listByIds(categoryIdListParam);
        } else {
            throw new ServiceException("该分销员暂时还没有分销商品");
        }
        return categoryList;
    }


    /**
     * 根据分类id查询分销商品信息
     * @param param
     * @return
     */
    private Page<DistributionGoodsVO> getDistributionGoodListByOpenIdAndCategoryInfo(DistributionGoodsSearchParams param) {
        Page<DistributionGoodsVO> page = baseMapper.getDistributionGoodListByOpenIdAndCategoryInfo(PageUtil.initPage(param), param);
        if (CollUtil.isNotEmpty(page.getRecords())) {
            return this.initDistributionGoodsVO(page, param.getDistributionId());
        }
        return new Page<>();
    }
}